import {
  createTreeNodes,
  type Node,
  type TreeNodes,
  treeNodeToMap,
} from '../array.mts';
import areaData from './areas.json' with { type: 'json' };

/**
 * 区域数据
 */
export type AreaType = {
  name: string;
  code: string;
  children?: AreaType[];
};

export interface AreaTypeNode extends AreaType {
  id: string;
  children?: AreaTypeNode[];
  parent?: AreaTypeNode;
}

/**
 * 区域树节点类型
 */
export type AreaTypeForNode = Pick<AreaType, 'name' | 'code'>;

/**
 * 格式化区域数据为树节点
 */
export const formatAreaToNode = () => {
  const process = (parent: AreaTypeNode | null = null, areas: AreaType[]) => {
    const node: AreaTypeNode[] = [];
    for (const element of areas) {
      node.push({
        name: element.name,
        code: element.code,
        id: element.code,
        parent,
      } as AreaTypeNode);
      if (element.children) {
        const cunode = node[node.length - 1];
        cunode.children = process(cunode, element.children);
      }
    }
    return node;
  };
  return process(null, areaData);
};

/**
 * 区域树节点
 */
export const areaNodes = formatAreaToNode();

/**
 * 区域树节点映射
 */
export const areaNodeMap = () => {
  const map = new Map<string, Node>();
  for (const area of areaNodes) {
    const areaMap = treeNodeToMap(area);
    areaMap.forEach((value, key) => {
      map.set(key, value);
    });
  }
  return map;
};

let cachedAreaTree: Readonly<TreeNodes<AreaTypeNode>> | null = null;

/**
 * 创建区域树
 */
export const createAreaTree = (
  newTree: boolean = false,
): TreeNodes<AreaTypeNode> => {
  if (!newTree && cachedAreaTree) return cachedAreaTree;

  const o: TreeNodes<AreaTypeNode> = createTreeNodes<AreaTypeNode>(
    formatAreaToNode(),
  );

  cachedAreaTree = o;
  return o;
};
